本文共 2248 字,大约阅读时间需要 7 分钟。
动态库在多进程环境下的行为可能会让人产生一些误解。很多人认为,同一动态库被多个进程打开时,实际上是共享同一个实例。这并不完全正确。实际上,每个进程在装载动态库时,会创建属于自己的独立实例。尽管动态库的代码和符号可能被多个进程共享,但每个进程都有自己独特的全局变量和互斥锁。这种行为会导致多个进程在使用相同动态库时,彼此之间无法直接看到对方的动态库实例。
为了验证这一点,我设计了一个简单的测试案例。以下是测试的详细步骤:
#ifndef _COUNT_H#define _COUNT_H#includeint count;pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;int get();void inc();#endif
#include "count.h"int get() { return count;}void inc() { pthread_mutex_lock(&mutex); count++; pthread_mutex_unlock(&mutex);} #include#include #include #include #include #define NUM 1000#define LIBPATH "/home/test1280/libcount.so"void *ThreadRun(void *arg) { void *handler = dlopen(LIBPATH, RTLD_LAZY); if (handler == NULL) { printf("ERROR:%s:dlopen\n", dlerror()); return; } void (*inc)() = (void (*)())dlsym(handler, "inc"); if (inc == NULL) { printf("ERROR:%s:dlsym\n", dlerror()); return; } int (*get)() = (int (*)())dlsym(handler, "get"); if (get == NULL) { printf("ERROR:%s:dlsym\n", dlerror()); return; } int i = 0; for (; i < NUM; i++) { inc(); usleep(1000 * 1000); printf("INFO:PID(%d):%d\n", getpid(), get()); } dlclose(handler);}int main() { pthread_t tid; pthread_create(&tid, NULL, ThreadRun, NULL); printf("create Thread OK!!!\n"); while (1); // 按住控制台,观察输出 return 0;}
gcc -fPIC -c count.cgcc -shared count.o -o libcount.sogcc -o main main.c -ldl -lpthread
./main
./main
观察输出结果:
create Thread OK!!! INFO:PID(5645):1 INFO:PID(5645):2 INFO:PID(5645):3 ...
create Thread OK!!! INFO:PID(5689):1 INFO:PID(5689):2 INFO:PID(5689):3 ...
从输出结果可以看出,两个进程各自独立地创建了自己的动态库实例,计数器从头开始,互不影响。这说明每个进程在装载动态库时,实际上是创建了独立的实例,包括各自的全局变量和互斥锁。
通过这些实验,我得出以下结论:
这些了解对于开发和优化多线程或多进程程序尤为重要。通过正确管理动态库的装载和使用,可以避免潜在的竞态条件和数据不一致问题。
转载地址:http://gtgs.baihongyu.com/